//---------------------------------界面逻辑与变量开始---------------------------------
// var	received = document.querySelector('#received'),
// 	peer_name = document.querySelector('#peerid');

// function trace(txt) {
//     console.log(txt);
//     received.innerHTML += txt + "<br />";
//     received.scrollTop = received.scrollHeight;
// }

//---------------------------------通用基础函数开始---------------------------------
//是否要采集音视频接口
import { message } from 'ant-design-vue'
var streamx
var servers_config = {
	iceServers: [
		{
			url: 'stun:60.216.60.60:3478',
		},
		{
			url: 'turn:60.216.60.60:3478',
			credential: 'link123',
			username: 'link',
		},
	],
}

const hasUserMedia = () => {
	navigator.getUserMedia =
		navigator.getUserMedia ||
		navigator.webkitGetUserMedia ||
		navigator.mozGetUserMedia ||
		navigator.msGetUserMedia
	return !!navigator.getUserMedia
}

//是否有pc接口
const hasRTCPeerConnection = () => {
	window.RTCPeerConnection =
		window.RTCPeerConnection ||
		window.webkitRTCPeerConnection ||
		window.mozRTCPeerConnection
	window.RTCSessionDescription =
		window.RTCSessionDescription ||
		window.webkitRTCSessionDescription ||
		window.mozRTCSessionDescription
	window.RTCIceCandidate =
		window.RTCIceCandidate ||
		window.webkitRTCIceCandidate ||
		window.mozRTCIceCandidate
	return !!window.RTCPeerConnection
}

//主动呼叫和外呼逻辑

class WebRTCEndpoint {
	constructor({
		remote_wnd = {},
		servers_config = {},
		usercode,
		type = 'video',
		duijiang = false,
		userRealName
	}) {
		this.servers_config = servers_config
		this.peer_conn = null
		this.userCode = usercode
		this.userRealName = userRealName
		//-- local

		this.local_sdp = null
		// -- remote

		this.remote_stream = []
		this.remote_wnd = remote_wnd
		console.log("this.remote_wnd", this.remote_wnd)
		this.remote_sdp = null

		this.video_width = 640
		this.video_height = 360

		this.is_call_out = false
		console.log("duijiang=================", duijiang)
		this.duijiang = duijiang
		this.type = type //是否视频还是音频
		// -- callback
		/// -- 本地sdp 生成， 需要挂载此回调来向外发送
		// this.on_local_sdp = null;
		/// -- 本地candidates， 需要挂载此回调来向外发送
		// this.on_candidate = null;
	}

	// 1 开始外呼
	start_call_peer() {
		//jsonObject1（video是视频，为false是音频，暂时写死===================）
		var jsonObject = {
			from: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
			to: this.userCode,
			cmd: 11,
			createTime: new Date().getTime(),
			msgType: 0,
			chatType: 2,
			content: {
				from: JSON.parse(sessionStorage.getItem('vuex')).userInfo
					.userCode,
				me: JSON.parse(sessionStorage.getItem('vuex')).userInfo
					.userCode,
				event: !this.duijiang ? 'SomeOneOnlinev' : 'SomeOneOnline',
				video: this.type == 'video' ? true : false,
			}, //测试使用
		}
		socket.send(JSON.stringify(jsonObject))
		console.log('aaaaaaaaaaaaaaaa   ' + JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode)
	}

	// 2 外呼收到 sdp应答 或 被呼叫
	set_remote_sdp(remote_sdp) {
		if (this.is_call_out) {
			this.peer_conn.setRemoteDescription(new RTCSessionDescription(remote_sdp), function () {
				console.log('dklsfj')
			}, function (error) {
				console.log('error', error)
				// alert("setRemoteDescription error has occurred:" + error);
			});
		} else {
			this._on_peer_called(remote_sdp)
		}
	}

	on_local_sdp(v) {
		// console.log('------------------------ on local sdp, peer_id =', v)
		var message = {
			content: {
				type: 'answer',
				description: v,
				event: 'SdpInfov',
			},
			from: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
			to: this.userCode,
			cmd: 11,
			createTime: new Date().getTime(),
			msgType: 0,
			chatType: 2,
		}
		if (!this.duijiang) {
			message.content.me = JSON.parse(
				sessionStorage.getItem('vuex')
			).userInfo.userCode
		}

		var data = JSON.stringify(message)
		// console.log('sdp',data)
		socket.send(data)
	}
	on_local_sdp2(v) {
		// console.log('------------------------ on local sdp, peer_id =', v)
		var message = {
			content: {
				type: "offer",
				description: v,
				event: "SdpInfov",
			},
			from: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
			to: this.userCode,
			cmd: 11,
			createTime: new Date().getTime(),
			msgType: 0,
			chatType: 2,
		}

		var data = JSON.stringify(message)
		// console.log('sdp',data)
		socket.send(data)
	}

	on_local_candidate(v) {
		let that = this
		var message = {}
		if (!this.duijiang) {
			message = {
				content: {
					label: v.candidate.sdpMLineIndex,
					id: v.candidate.sdpMid,
					candidate: v.candidate.candidate,
					event: "IceInfov",
				},
				from: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
				to: that.userCode,
				cmd: 11,
				createTime: new Date().getTime(),
				msgType: 0,
				chatType: 2,
			}
		} else {
			message = {
				content: {
					label: v.candidate.sdpMLineIndex,
					id: v.candidate.sdpMid,
					candidate: v.candidate.candidate,
					event: "IceInfo",
					me: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
				},
				from: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
				to: that.userCode,
				cmd: 11,
				createTime: new Date().getTime(),
				msgType: 0,
				chatType: 2,
			}
		}
		var data = JSON.stringify(message)
		socket.send(data)
	}

	//接收到远端呼叫 ， 会通过on_local_sdp 回调把本地sdp 返回
	_on_peer_called(remote_sdp) {
		this.is_call_out = false

		this.peer_conn = new RTCPeerConnection(this.servers_config)

		var ssdp = new RTCSessionDescription(remote_sdp)

		console.log('=============== set remote ssdp = ', remote_sdp)

		var ep = this

		ep.peer_conn.ontrack = function (e) {
			console.log(
				'------------------------------------------------ on add track ',
				e
			)
			if (e.track.kind == 'audio') {
				console.log('audio track received')
			} else {
				ep.remote_stream = e.streams[0]
				ep.remote_wnd.srcObject = ep.remote_stream
			}
		}

		ep.peer_conn.onconnectionstatechange = function (event) {
			switch (ep.peer_conn.connectionState) {
				case "closed":
				case 'disconnected':
				case 'failed':
					console.log(`${ep.userRealName}挂断了`)
					ep.peer_conn.close()
					message.warning(`${ep.userRealName}挂断了`)
					break;
			}
		}

		ep.peer_conn.onicecandidate = function (content) {
			if (content.candidate) {
				console.log('candidates')
				ep.on_local_candidate(content)
			}
		}
		this.peer_conn.setRemoteDescription(
			ssdp,
			function () {
				var is_send_audio = true
				var send_video_count = 1
				console.log(
					'=============== set remote offer ssdp  success = ',
					ssdp
				)

				if (is_send_audio == true || send_video_count > 0) {
					ep.peer_conn.addStream(streamx)
					ep.peer_conn.createAnswer(
						function (answer) {
							ep.local_sdp = answer.sdp
							ep.peer_conn.setLocalDescription(
								answer,
								function () {
									console.log(
										"send the offer to a server to be forwarded to the friend you're calling"
									)
								},
								function (error) {
									console.log(error)
								}
							)

							//!!!! 回调出去
							if (ep.on_local_sdp) {
								ep.on_local_sdp(answer.sdp)
							}
						},
						function (error) {
							console.log('error', error)
							// alert('setLocalDescription error has occurred.')
						}
					)
				}
			},
			function (error) {
				console.log('error', error)
				// alert('setRemoteDescription error has occurred:' + error)
			}
		)

	}

	// ---- 发送接收端都要调用
	set_ice_candidate(candidate) {
		this.peer_conn.addIceCandidate(new RTCIceCandidate(candidate))
	}

	hang_up() {
		console.log('hang_up', this.peer_conn)

		if (this.peer_conn) {
			this.peer_conn.close()
		} else {
			window.location.reload();
		}
		this.peer_conn = null
	}
	//
}

/////////////////////////////////// 进入 测试流程 ////////////////////////////
// ------ 初始化一个 WebRTCEndpoint 对象

let socket, webrtc_ep;
function keepAlive() {
	var timeout = 20000;
	if (socket.readyState == socket.OPEN) {
		socket.send('');
	}
	setTimeout(keepAlive, timeout);
}
function main(callButton, ByeButton, mineVideo, domArr, that) {
	var my_id = 0
	var peer_idx = 0
	var out = false
	var uri =
		'wss://jb.tiandao.fun:8881?username=' +
		JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode +
		'&password=' +
		JSON.parse(sessionStorage.getItem('vuex')).userInfo.password + '&token=1'
	socket = new WebSocket(uri)

	webrtc_ep = []

	if (!hasUserMedia() || !hasRTCPeerConnection()) {
		alert('抱歉，你的浏览器不支持WebRTC')
		return
	}
	let checkedUser = JSON.parse(sessionStorage.getItem('vuex')).checkedUser

	navigator.getUserMedia(
		{
			audio: true,
			video: { width: { exact: 640 }, height: { exact: 360 } }
			// video:true

		},
		function (stream1) {
			if (mineVideo) {
				mineVideo.srcObject = stream1
				mineVideo.volume = 0.0
				streamx = stream1
			}

		},
		function (error) {
			alert('第一路音视频采集失败:')
		}
	)
	callButton && callButton.addEventListener('click', function () {
		checkedUser = JSON.parse(sessionStorage.getItem('vuex')).checkedUser
		// if (!this.checkedUser.length) {
		// 	message.error('请先选择要通话的人员')
		// 	return false
		// }
		// let isonline = this.checkedUser.some((item) => item.isOnline == 1)
		// if (!isonline) {
		// 	message.error('您要通话的人都不在线')
		// 	return false
		// }
		// this.chatList = this.checkedUser.filter(
		// 	(item) => item.isOnline == 1
		// )
		if (checkedUser && checkedUser.length) {
			if (!checkedUser.length) {
				message.error('请先选择要通话的人员')
				return false
			}
			let isonline = checkedUser.some((item) => item.isOnline == 1)
			if (!isonline) {
				message.error('您要通话的人都不在线')
				return false
			}
			let chatList = checkedUser.filter((item) => item.isOnline == 1)
			chatList.forEach((item, index) => {
				webrtc_ep[index] = new WebRTCEndpoint({
					remote_wnd: domArr[index],
					servers_config: servers_config,
					usercode: item.userCode,
					userRealName: item.userRealName
				})
				webrtc_ep[index].start_call_peer()
			})
		}
	})

	ByeButton && ByeButton.addEventListener('click', function () {
		Object.keys(webrtc_ep).forEach(function (key) {
			webrtc_ep[key].hang_up()
		})
		checkedUser = JSON.parse(sessionStorage.getItem('vuex')).checkedUser
		checkedUser.map(item => {
			const jsonObject = {
				me: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
				to: item.userCode,
				cmd: 11,
				createTime: new Date().getTime(),
				msgType: 0,
				chatType: 2,
				content: {
					me: JSON.parse(sessionStorage.getItem('vuex')).userInfo.userCode,
					event: 'HangUp',
				},
			}
			socket.send(JSON.stringify(jsonObject))
		})
	})
	// Handle any errors that occur.
	socket.onerror = function (error) {
		console.log('WebSocket Error: ' + error)
	}

	// Show a connected message when the WebSocket is opened.
	socket.onopen = function (content) {
		keepAlive();
		console.log(' websocket on open !')
	}

	// Handle messages sent by the server.
	socket.onmessage = function (content) {
		// console.log('JSON.parse(content.data)', JSON.parse(content.data).data)
		if (
			JSON.parse(content.data).data &&
			JSON.parse(content.data).data.content
		) {
			var a = JSON.parse(JSON.parse(content.data).data.content)
			// console.log(a)
			var r
			var b = JSON.parse(content.data).data
			var c
			JSON.parse(sessionStorage.getItem('vuex')).checkedUser.forEach(
				(item, index) => {
					if (b.from == item.userCode) {
						c = index
					} else {
						return
					}
				}
			)
			if (a && a.event == 'sos') {
				console.log("来电话了")
				if (that.$route.path !== '/warning') {
					// that.toPath(content,warning)
					// let vuex = JSON.parse(sessionStorage.getItem('vuex'))
					// vuex.flag = content
					// sessionStorage.setItem('vuex',JSON.stringify(vuex))
					that.setFlag(content)
					that.$router.push('warning')
					return
				}
			}
			// console.log(c)
			if (a && a.event == 'SdpInfov') {
				r = {
					type: a.type,
					sdp: a.description,
				}
				if (out) {
					webrtc_ep[b.from].set_remote_sdp(r)
				} else {
					webrtc_ep[c] && webrtc_ep[c].set_remote_sdp && webrtc_ep[c].set_remote_sdp(r)
				}
			} else if (a && a.event == 'IceInfov') {
				r = {
					candidate: a.candidate,
					sdpMid: a.id,
					sdpMLineIndex: a.label,
				}
				if (out) {
					webrtc_ep[b.from].set_ice_candidate(r)
				} else {
					webrtc_ep[c] && webrtc_ep[c].set_ice_candidate && webrtc_ep[c].set_ice_candidate(r)
				}
			}
			if (a && a.event == "SdpInfo") {
				r = {
					type: a.type,
					sdp: a.description,
				}
				webrtc_ep[c].set_remote_sdp(r)
			} else if (a && a.event == "IceInfo") {
				r = {
					candidate: a.candidate,
					sdpMid: a.id,
					sdpMLineIndex: a.label,
				}
				webrtc_ep[c].set_ice_candidate(r)
			} else if (a && a.event == "SomeOneOnlinev") {
				if (that.$route.path !== '/monitor') {
					that.toPath(content,a.userRealName)
					return
				}
				console.log(b.from + "dslkfjlkdsfljkl")
				out = true
				webrtc_ep[b.from] = new WebRTCEndpoint({
					remote_wnd: domArr[0],
					servers_config: servers_config,
					usercode: b.from,
					userRealName: b.userRealName
				})

				webrtc_ep[b.from].is_call_out = true
				webrtc_ep[b.from].peer_conn = new RTCPeerConnection(
					webrtc_ep[b.from].servers_config,
				)
				webrtc_ep[b.from].peer_conn.addStream(streamx)
				webrtc_ep[b.from].peer_conn.ontrack = function (e) {

					console.log(
						"------------------------------------------------ on add track ",
						e
					)
					if (e.track.kind == "audio") {
						console.log("audio track received")
					} else {
						webrtc_ep[b.from].remote_stream = e.streams[0]
						webrtc_ep[b.from].remote_wnd.srcObject =
							webrtc_ep[b.from].remote_stream
					}
				}

				webrtc_ep[b.from].peer_conn.onconnectionstatechange = function (e) {
					console.log('-------------------', 'onconnectionstatechange')
					if (e.target.connectionState === 'closed' ||
						e.target.connectionState === 'disconnected' ||
						e.target.connectionState === 'failed') {
						webrtc_ep[b.from].hang_up()
						message.warning(`${a.userRealName}挂断了`)
					}
				}

				webrtc_ep[b.from].peer_conn.onicecandidate = function (content) {
					if (content.candidate) {
						console.log("是独立开发接口的历史交锋了")
						webrtc_ep[b.from].on_local_candidate(content)
					}
				}
				webrtc_ep[b.from].peer_conn.createOffer(
					function (offer) {
						console.log(" local sdp = ", offer.sdp)
						webrtc_ep[b.from].local_sdp = offer.sdp

						webrtc_ep[b.from].peer_conn.setLocalDescription(
							offer,
							function () {
								console.log(
									"send the offer to a server to be forwarded to the friend you're calling"
								)
							},
							function (error) {
								console.log(error)
							}
						)

						//!!!! 回调出去
						if (webrtc_ep[b.from].on_local_sdp2) {
							webrtc_ep[b.from].on_local_sdp2(offer.sdp)
						}
					},
					function (error) {
						console.log('error', error)
						// alert("setLocalDescription error has occurred.")
					}
				)
				webrtc_ep[b.from].peer_conn.o
			} else if (a && a.event && a.event === 'HangUp') {
				// webrtc_ep.forEach(item => {
				// 	if (item.userCode === a.me) {
				// 		item.hang_up()
				// 	}
				// })
				checkedUser = JSON.parse(sessionStorage.getItem('vuex')).checkedUser
				checkedUser.forEach(item => {
					if (item.userCode === a.me) {
						message.warning(`${item.userRealName}挂断了`)
					}
				})

			}

		}
	}

	// Show a disconnected message when the WebSocket is closed.
	socket.onclose = function (content) {
		console.log('websocket断开' + content.code + ',' + content.reason + ',' + content.wasClean)
		console.log('content onclose', content);
		Object.keys(webrtc_ep).forEach(function (key) {
			webrtc_ep[key].hang_up()
		})
	}
}
function emitMessage(context) {
	if (context.data) {
		socket.onmessage(context)
	}
}

export {
	main,
	emitMessage,
	hasUserMedia,
	hasRTCPeerConnection,

}